
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include "chapter_4_1.h"

using namespace std;

void Chapter_4_1::commit(){
    std_file_descriptors();
}

void  Chapter_4_1::std_file_descriptors(){
    by_number();
    cout << "-------------------------" << endl;
    by_posix_name();
    cout << "-------------------------" << endl;
    by_stdio_stream();
    cout << "-------------------------" << endl;
    read_by_number();
    cout << "-------------------------" << endl;
    read_by_posix_name();
    cout << "-------------------------" << endl;
    read_by_stdio_stream();
    cout << "-------------------------" << endl;
    critical_test();
    cout << "-------------------------" << endl;
}

void  Chapter_4_1::by_number(){

    cout << "use file descriptors by number:" << endl;

    const char *str = "this is 1.\n";
    write(1, str, strlen(str));
    str = "this is 2.\n";
    write(2, str, strlen(str));
}

void  Chapter_4_1::by_posix_name(){
    // to use STDOUT_FILENO STDERR_FILENO STDIN_FILENO, please include <unistd.h>
    cout << "use file descriptors POSIX name:" << endl;

    const char *str = "this is STDOUT_FILENO.\n";
    write(STDOUT_FILENO, str, strlen(str));

    str = "this is STDERR_FILENO.\n";
    write(STDERR_FILENO, str, strlen(str));
}
    
void  Chapter_4_1::by_stdio_stream(){
    cout << "use stdio stream:" << endl;
    fprintf(stdout, "this is stdout.\n");
    fprintf(stderr, "this is stderr.\n");
}

void  Chapter_4_1::read_by_number(){
    cout << "use file descriptors by number to input a string:" << endl;
    char buf[100];
    int count = read(0, buf, 100);
    buf[count] = '\0';
    cout << buf << endl;
}

void  Chapter_4_1::read_by_posix_name(){
    cout << "use file descriptors by posix name to input a string:" << endl;
    char buf[100];
    int count = read(STDIN_FILENO, buf, 100);
    buf[count] = '\0';
    cout << buf << endl;
}

void  Chapter_4_1::read_by_stdio_stream(){
    cout << "use file descriptors by stdio stream to input a string(must type more than 9 letters):" << endl;
    char buf[100];
    int count = fread(buf, 10, 1, stdin);
    buf[count*10] = '\0';
    cout << buf << endl;
}

static void critical_output(){
    fprintf(stdin, "\twrite to stdin.\n"); 
    const char *str = "\twrite to 0.\n";
    write(0, str, strlen(str));
    str = "\twrite to STDIN_FILENO.\n";
    write(STDIN_FILENO, str, strlen(str));


}

static void critical_input_1(){
    char buf[100];
    int count = read(1, buf, 100);
    buf[count] = '\0';
    cout << buf << endl;
    
    
}
static void critical_input_2(){
    char buf[100];
    int count = read(2, buf, 100);
    buf[count] = '\0';
    cout << buf << endl;
    
    
}

void Chapter_4_1::critical_test(){
    cout << "critical test:\t write to stdin, 0 and STDIN_FILENO.  (to stdin's str does not work!)" << endl;
    critical_output();
    cout << "critical test:\t read from 1." << endl;
    critical_input_1();
    cout << "critical test:\t read from 2." << endl;
    critical_input_2();
}



